#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>

//https://cdn-gomark.17zuoye.cn/81bf91/training/opus/20210226/81bf91de780d11eb818402420a082354
struct MemoryStruct {
  char *memory;
  size_t size;
};
 
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;
 
  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
 
  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}
 
int main(int argc, char *argv[])
{
    CURL *curl_handle;             //定义CURL类型的指针
    CURLcode res;           //定义CURLcode类型的变量，保存返回状态码
    struct MemoryStruct chunk;
    chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */ 
    chunk.size = 0;    /* no data at this point */ 
 
    if(argc!=2)
    {
        printf("Usage : file <url>;/n");
        exit(1);
    }

    curl_handle = curl_easy_init();        //初始化一个CURL类型的指针
    if(curl_handle != NULL)
    {
        curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]);       
        curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
 
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
        res = curl_easy_perform(curl_handle);
        if(res != CURLE_OK) {
          fprintf(stderr, "curl_easy_perform() failed: %s\n",
          curl_easy_strerror(res));
        }
        else {
              printf("%s\n", chunk.memory);
              printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
        }
        curl_easy_cleanup(curl_handle);
    }
    return 0;
}

